#ifndef DATACENTER_H
#define DATACENTER_H

#include <QObject>
#include <QStandardPaths>
#include <QDir>
#include <QFile>
#include <QJsonObject>
#include <QJsonDocument>

#include "data.h"
#include "../network/netclient.h"

namespace model {

class DataCenter : public QObject
{
    Q_OBJECT
public:
    static DataCenter* getInstance();

    ~DataCenter();

    // 创建出数据文件
    void initDataFile();
    // 将数据保存到数据文件
    void saveDataFile();
    // 从数据文件中加载数据
    void loadDataFile();

    QString getLoginSessionId();

    // client send ping request
    void ping();

    // get personal information from server
    void getMyselfAsync();
    void resetMyself(std::shared_ptr<bite_im::GetUserInfoRsp> rsp);
    UserInfo* getMyself();

    // get friendList from server
    void getFriendListAsync();
    void resetFriendList(std::shared_ptr<bite_im::GetFriendListRsp> rsp);
    QList<UserInfo>* getFriendList();

    // get chatSessionList from server
    void getChatSessionListAsync();
    void resetChatSessionList(std::shared_ptr<bite_im::GetChatSessionListRsp> rsp);
    QList<ChatSessionInfo>* getChatSessionList();

    // get applyList from server
    void getApplyListAsync();
    void resetApplyList(std::shared_ptr<bite_im::GetPendingFriendEventListRsp> rsp);
    QList<UserInfo>* getApplyList();

    // get recentMsgList from server
    void getRecentMessageListAsync(const QString& chatSessionId, bool updateUI);
    void resetRecentMessageList(std::shared_ptr<bite_im::GetRecentMsgRsp> rsp, const QString& chatSessionId);
    QList<Message>* getRecentMessageList(const QString& chatSessionId);

    void sendTextMessageAsync(const QString& chatSessionId, const QString& text);

    void modifyNickNameAsync(const QString& newName);
    void resetNickname(const QString& newName);

    void modifyDescriptionAsync(const QString& newDesc);
    void resetDescription(const QString& newDesc);

    void getVerifyCodeAsync(const QString& newPhone);
    void resetVerifyCodeId(const QString& vcId);
    const QString& getVerifyCodeId();

    void modifyPhoneAsync(const QString& newPhone, const QString& verifyCodeId, const QString& verifyCode);
    void resetPhone(const QString& newPhone);

    void modifyAvatarAsync(const QByteArray& image);
    void resetAvatar(const QByteArray& image);

    void deleteFriendAsync(const QString& userId);
    void deleteFriend(const QString& userId);

    void sendFriendApplyAsync(const QString& userId);
    void addFriendApply(const UserInfo& userInfo);

    void acceptFriendApplyAsync(const QString& userId);
    void rejectFriendApplyAsync(const QString& userId);

    void createGroupChatSessionAsync(const QList<QString>& userIdList);

    void setCurrentSessionId(const QString& chatSessionId);
    QString getCurrentSessionId();

    ChatSessionInfo* findChatSessionInfoById(const QString& chatSessionId);
    ChatSessionInfo* findChatSessionInfoByUserId(const QString& userId);
    UserInfo* findUserInfoById(const QString& userId);

    void topChatSesssionInfo(const ChatSessionInfo& chatSessionInfo);
    model::UserInfo removeFromApplyList(const QString& userId);

    // add msg to recentMsgHash
    void addMessage(const model::Message& msg);

    void clearUnreadMsgCount(const QString& chatSessionId);
    void addUnreadMsgCount(const QString& chatSessionId);
    int getUnreadMsgCount(const QString& chatSessionId);

private:
    DataCenter();

    static DataCenter* instance;

    // 登录会话id
    QString loginSessionId = "";
    // 当前客户端的用户信息
    UserInfo* myself = nullptr;
    // 好友列表
    QList<UserInfo>* friendList = nullptr;
    // 聊天会话列表
    QList<ChatSessionInfo>* chatSessionList = nullptr;
    // 聊天会话中的所有用户信息(群聊),<聊天会话id,成员链表>
    QHash<QString, QList<UserInfo>>* memberHash = nullptr;
    // 当前所处的会话id
    QString curSessionId = "";
    // 好友申请列表
    QList<UserInfo>* applyList = nullptr;
    // 每个会话的最近消息列表,<会话id,最近消息列表>
    QHash<QString, QList<Message>>* recentMsgHash = nullptr;
    // 每个会话的未读消息个数,<会话id,个数>
    QHash<QString, int>* unreadMsgHash = nullptr;
    // 好友搜索结果列表
    QList<UserInfo>* searchResultList = nullptr;
    // 历史消息结果列表
    QList<Message>* historyMsgList = nullptr;
    // 短信验证码验证id
    QString verifyCodeId = "";

    // 客户端
    network::NetClient netClient;

signals:
    void getMyselfDone();
    void getFriendListDone();
    void getChatSessionListDone();
    void getApplyListDone();
    void getRecentMessageListDone(const QString& chatSessionId);
    void getRecentMessageListDoneNoUI(const QString& chatSessionId);
    void sendMessageDone(model::MessageType type, const QByteArray& content, const QString& extraInfo);
    void addSelfMessageDone(const QString& chatSessionId);
    void receiveMessageDone(const model::Message& lastMsg);
    void modifyNicknameDone();
    void modifyDescriptionDone();
    void getVerifyCodeDone();
    void modifyPhoneDone();
    void modifyAvatarDone();
    void deleteFriendDone();
    void clearCurrentChatSession();
    void sendFriendApplyDone();
    void addFriendApplyDone();
    void acceptFriendApplyDone();
    void agreeFriendApplyDone();
    void rejectFriendApplyDone();
    void createGroupChatSessionDone();
    void newChatSessionDone();
};

} // end namespace

#endif // DATACENTER_H
